﻿using System;
using CoreEx.Common.Proxy;
using LinFu.AOP.Interfaces;
using LinFu.IoC.Configuration;
using LinFu.IoC.Interfaces;
using LinFu.Proxy.Interfaces;

namespace CoreEx.ServiceModel.Implementation
{
    /// <summary>
    /// Intercepts constructor calls made to a service contract proxy type.
    /// </summary>
    [Implements(typeof(IConstructorInterceptor), ServiceName = "ServiceContractConstructorInterceptor")]
    public class ServiceContractConstructorInterceptor : IConstructorInterceptor, IInitialize
    {
        private IServiceContainer _serviceContainer;
        private readonly Type _serviceType;


        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceContractConstructorInterceptor"/> class.
        /// </summary>
        /// <param name="serviceType">The type of service to create as the target instance.</param>
        public ServiceContractConstructorInterceptor(Type serviceType)
        {
            _serviceType = serviceType;
        }

        /// <summary>
        /// This method is called during execution of the target constructor.
        /// </summary>
        /// <param name="info">The <see cref="IInitalizationInfo"/> associated with the constructor call.</param>
        /// <seealso cref="IInvocationInfo"/>
        public void Intercept(IInitalizationInfo info)
        {
            var serviceInstance = _serviceContainer.GetService(_serviceType);
            ((IProxy) info.Target).Interceptor = new ServiceContractInterceptor(serviceInstance);            
        }

        /// <summary>
        /// Initializes this service instance.
        /// </summary>        
        public void Initialize(IServiceContainer source)
        {
            _serviceContainer = source;
        }
    }
}
